#include "./../../Headers/mathematics/math_va.h"

namespace Mathematics {

	//! Aleatory samples
	/*!
		A namespace for containing a sort of aleatory variable generator
	*/
	namespace Sample{
		
		int Poisson( const double &lambda, const double &t ){
			const double lambda_t = lambda*t;
			const uint bound = Upp( 2.0*lambda_t );
			const double sample = dRand() * exp( lambda_t );
			double sum = 0.0;
			
			for( usint i = 0; i < bound; ++i ){
				sum += pow( lambda_t , i ) / Fat( i );
				if( sum >= sample ){
					return i;
				}
			}
			return bound;
		};
		
		void SampleTest(){
			cout << endl << "---SampleTest---" << endl;
			
			cout << "Uniform(0.0,1.0)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << dRand() << endl;
			}
			cout << "Uniform(-2.0,3.5)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << Uniform(-2.0,3.5) << endl;
			}
			cout << "Exponential(2.0)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << Exponential(2.0) << endl;
			}
			cout << "Bernoulli(0.3)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << Bernoulli(0.3) << endl;
			}
			cout << "Poisson(1.0,2.0)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << Poisson(1.0,2.0) << endl;
			}
			cout << "Geometric(0.75)" << endl;
			for( usint i = 0; i < 10; ++i ){
				cout << "i: " << i << ", " << Geometric(0.75) << endl;
			}
			
			cout << "---TestEnd---" << endl;
		};
	};
};
